1
|
|
package net.sf.flock.support;
|
2
|
|
|
3
|
|
import java.net.URL;
|
4
|
|
import java.util.ArrayList;
|
5
|
|
import java.util.Arrays;
|
6
|
|
import java.util.Iterator;
|
7
|
|
import java.util.List;
|
8
|
|
|
9
|
|
import net.sf.flock.FeedFactoryI;
|
10
|
|
import net.sf.flock.FeedI;
|
11
|
|
import net.sf.flock.FeedInfoI;
|
12
|
|
import net.sf.flock.FlockResourceException;
|
13
|
|
import net.sf.flock.MetaData;
|
14
|
|
import net.sf.flock.SubscriptionI;
|
15
|
|
import net.sf.flock.SubscriptionInfoI;
|
16
|
|
import net.sf.flock.SubscriptionManagerI;
|
17
|
|
import net.sf.flock.parser.FeedLoader;
|
18
|
|
import net.sf.flock.parser.UnsupportedFeedFormatException;
|
19
|
|
import net.sf.flock.util.DocumentLoader;
|
20
|
|
|
21
|
|
import org.apache.log4j.LogManager;
|
22
|
|
import org.apache.log4j.Logger;
|
23
|
|
import org.jdom.Document;
|
24
|
|
|
25
|
|
public abstract class AbstractSubscriptionManager implements SubscriptionManagerI {
|
26
|
|
|
27
|
|
private final static Logger LOGGER = LogManager.getLogger(AbstractSubscriptionManager.class);
|
28
|
|
|
29
|
0
|
public SubscriptionI[] subscribe(final URL location, final MetaData metaData) throws FlockResourceException {
|
30
|
0
|
return this.subscribe(new SubscriptionInfoI() {
|
31
|
|
|
32
|
0
|
public URL getLocation() {
|
33
|
0
|
return location;
|
34
|
|
}
|
35
|
0
|
public MetaData getMetaData() {
|
36
|
0
|
return metaData;
|
37
|
|
}
|
38
|
|
|
39
|
0
|
public FeedInfoI getFeedInfo() {
|
40
|
0
|
return new FeedInfoI() {
|
41
|
0
|
public String getTitle() {
|
42
|
0
|
return "New feed";
|
43
|
|
}
|
44
|
0
|
public URL getSite() {
|
45
|
0
|
return null;
|
46
|
|
}
|
47
|
0
|
public SubscriptionInfoI getSubscriptionInfo() {
|
48
|
0
|
return null;
|
49
|
|
}
|
50
|
|
|
51
|
|
};
|
52
|
|
}
|
53
|
|
|
54
|
|
}, true);
|
55
|
|
}
|
56
|
|
|
57
|
|
protected abstract SubscriptionI createSubscription(SubscriptionInfoI subscriptionInfo) throws FlockResourceException;
|
58
|
|
|
59
|
|
/**
|
60
|
|
* @return List of new ItemI objects
|
61
|
|
*/
|
62
|
0
|
protected List refresh(SubscriptionI subscription) throws FlockResourceException {
|
63
|
0
|
FeedLoader factory = new FeedLoader(this.getFeedFactory());
|
64
|
0
|
Document doc = new DocumentLoader().loadDocument(subscription.getLocation());
|
65
|
0
|
FeedI feed = factory.parseFeed(subscription, doc);
|
66
|
0
|
return subscription.getFeed().merge( feed );
|
67
|
|
}
|
68
|
|
|
69
|
|
protected abstract FeedFactoryI getFeedFactory();
|
70
|
|
|
71
|
0
|
public SubscriptionI[] subscribe(SubscriptionInfoI si, boolean loadFeed) throws FlockResourceException {
|
72
|
|
|
73
|
0
|
Document doc = new DocumentLoader().loadDocument(si.getLocation());
|
74
|
|
|
75
|
0
|
try {
|
76
|
|
|
77
|
0
|
SubscriptionI subscription = this.createSubscription(si);
|
78
|
|
|
79
|
0
|
if (loadFeed) {
|
80
|
0
|
this.refresh(subscription);
|
81
|
|
}
|
82
|
|
|
83
|
0
|
return new SubscriptionI[] { subscription };
|
84
|
|
|
85
|
|
} catch (UnsupportedFeedFormatException e) {
|
86
|
|
|
87
|
0
|
LOGGER.info("Unknown feed format, trying OPML...");
|
88
|
0
|
OpmlSubscriptionImport importer = new OpmlSubscriptionImport( si.getMetaData() );
|
89
|
|
|
90
|
0
|
if (!importer.isSuitable(doc)) {
|
91
|
0
|
throw new FlockResourceException("Unsupported feed format");
|
92
|
|
}
|
93
|
|
|
94
|
0
|
LOGGER.info("Parsing as OPML");
|
95
|
0
|
SubscriptionInfoI[] subInfos = importer.load(doc);
|
96
|
|
|
97
|
0
|
List subs = new ArrayList(subInfos.length);
|
98
|
0
|
for (int i=0; i<subInfos.length; i++) {
|
99
|
0
|
try {
|
100
|
0
|
subs.addAll( Arrays.asList(
|
101
|
|
this.subscribe(subInfos[i], false)
|
102
|
|
) );
|
103
|
|
} catch (FlockResourceException ex) {
|
104
|
0
|
LOGGER.warn("Unable to subscribe to "+subInfos[i].getLocation(), ex);
|
105
|
|
}
|
106
|
|
}
|
107
|
|
|
108
|
0
|
return (SubscriptionI[])subs.toArray( new SubscriptionI[subs.size()] );
|
109
|
|
}
|
110
|
|
|
111
|
|
}
|
112
|
|
|
113
|
|
|
114
|
|
boolean alreadyRunningRefreshThread = false;
|
115
|
|
|
116
|
|
/**
|
117
|
|
* TODO: implement proper balking
|
118
|
|
*/
|
119
|
0
|
public boolean refreshAll() {
|
120
|
0
|
synchronized(this) {
|
121
|
0
|
if (alreadyRunningRefreshThread)
|
122
|
0
|
return false;
|
123
|
0
|
alreadyRunningRefreshThread = true;
|
124
|
|
}
|
125
|
0
|
Thread t = new Thread("FlockAsyncRefresh") {
|
126
|
0
|
public void run() {
|
127
|
0
|
try {
|
128
|
0
|
doRefreshAll();
|
129
|
|
} catch (FlockResourceException e) {
|
130
|
0
|
LOGGER.warn("Problem in refreshAll", e);
|
131
|
|
} finally {
|
132
|
0
|
alreadyRunningRefreshThread = false;
|
133
|
|
}
|
134
|
|
}
|
135
|
|
};
|
136
|
0
|
t.start();
|
137
|
0
|
return true;
|
138
|
|
}
|
139
|
|
|
140
|
0
|
protected void doRefreshAll() throws FlockResourceException {
|
141
|
0
|
for (Iterator i=this.getSubscriptionInfos().iterator(); i.hasNext(); ) {
|
142
|
0
|
SubscriptionInfoI si = (SubscriptionInfoI) i.next();
|
143
|
0
|
SubscriptionI subscription = this.getSubscription( si.getLocation() );
|
144
|
0
|
try {
|
145
|
0
|
refresh( subscription );
|
146
|
|
} catch (FlockResourceException e) {
|
147
|
0
|
LOGGER.warn("Failed to refresh feed["+subscription.getLocation()+"], skipping", e);
|
148
|
|
}
|
149
|
|
}
|
150
|
|
}
|
151
|
|
|
152
|
|
|
153
|
|
}
|
154
|
|
|